import euclid,bat
from pybass import *

#todo: improve walls reflection

class Ball(object):
    def __init__(self,g,pos,dir,surprise,size):
        self.g=g
        self.pos=pos
        self.dir=dir
        self.surprise=surprise
        self.size=size
        self.alive=True
        if self.surprise==0:
            if size==0:
                self.img=g.LoadImg('balls/smallest_red_ball.png')
            elif size==1:
                self.img=g.LoadImg('balls/smaller_red_ball.png')    
            else:
                self.img=g.LoadImg('balls/small_red_ball.png')
        else:
            self.img=g.LoadImg('balls/question.png')
        self.radius=self.img.width//2

    def DoSurprise(self,q):
        self.alive=False
        if q==1:
            if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_woohoo,0),1)
            self.g.ball_speed-=25
            if self.g.ball_speed<50:
                self.g.score+=500
                self.g.hud.LabelScore()
                self.g.ball_speed=50
        elif q==2:
            if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_doh,0),1)            
            self.g.ball_speed+=25
            if self.g.ball_speed>150:
                self.g.score-=500
                self.g.hud.LabelScore()
                self.g.ball_speed=150
        elif q==3:
            if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_woohoo,0),1)            
            self.g.score+=500
            self.g.hud.LabelScore()
        elif q==4:
            if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_doh,0),1)
            self.g.score-=500
            self.g.hud.LabelScore()
        elif q==5:
            if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_woohoo,0),1)
            self.g.lives+=1
            self.g.hud.LabelLives()
        elif q==6:
            if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_doh,0),1)
            self.g.lives-=1
            self.g.hud.LabelLives()
        elif q==7:
            if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_doh,0),1)
            if self.g.bat: del self.g.bat
            self.g.bat_size-=1
            if self.g.bat_size<0:
                self.g.score-=500
                self.g.hud.LabelScore()
                self.g.bat_size=0
            self.g.bat=bat.Bat(self.g,self.g.bat_size)
        elif q==8:
            if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_woohoo,0),1)
            if self.g.bat: del self.g.bat
            self.g.bat_size+=1
            if self.g.bat_size>2:
                self.g.score+=500
                self.g.hud.LabelScore()
                self.g.bat_size=2
            self.g.bat=bat.Bat(self.g,self.g.bat_size)
        elif q==9:
            if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_doh,0),1)
            self.g.ball_size-=1
            if self.g.ball_size<0:
                self.g.score-=500
                self.g.hud.LabelScore()
                self.g.ball_size=0
            self.g.ResizeBalls()
        #if q==10:
        else:
            if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_woohoo,0),1)
            self.g.ball_size+=1
            if self.g.ball_size>0:
                self.g.score+=500
                self.g.hud.LabelScore()
                self.g.ball_size=2
            self.g.ResizeBalls()

    def Reflect(self,n):
        temp=self.d
        self.d=self.d.reflect(n)
        self.v=self.v.reflect(n)
        self.a=self.a.reflect(n)
        if self.d==temp:
            self.d=-self.d
            self.v=-self.v
            self.a=-self.a

    def Normal(self,l):
        p1=l.p1
        p2=l.p2
        n=euclid.Vector2((p1.y-p2.y),-(p1.x-p2.x)).normalized()
        return n

    def ChkWallCollisions(self):
        # Top wall
        if self.dir.y>0:
            if self.pos.y+self.radius>=self.g.height:
                if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_wall,0),1)
                n=euclid.Vector2(0.0,-1.0)
                self.dir=self.dir.reflect(n)
                self.pos.y=self.g.height-self.radius
        # Bottom wall
        if self.dir.y<0:
            if self.pos.y-self.radius<=0:
                if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_doh,0),1)
                #Todo: Do we want to reduce lives for missed surprises
                self.g.lives-=1
                self.g.hud.LabelLives()
                if self.surprise==0:
                    n=euclid.Vector2(0.0,1.0)
                    self.dir=self.dir.reflect(n)
                else:
                    #Todo: Penalize score for missed surprises as well?
                    #self.g.score-=100
                    self.alive=False
        # Left wall
        if self.dir.x<0:
            if self.pos.x-self.radius<=0:
                if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_wall,0),1)
                n=euclid.Vector2(1.0,0.0)
                self.dir=self.dir.reflect(n)
                self.pos.x=self.radius
        # Right wall
        if self.dir.x>0:
            if self.pos.x+self.radius>=self.g.width:
                if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_wall,0),1)
                n=euclid.Vector2(-1.0,0.0)
                self.dir=self.dir.reflect(n)
                self.pos.x=self.g.width-self.radius

    def ChkBatCollisions(self):
        # Top of bat
        if self.dir.y<0:
            if self.pos.y-self.radius<=self.g.bat.maxy and self.pos.y+self.radius>self.g.bat.maxy:
                x1=self.pos.x>=self.g.bat.pos.x-self.g.bat.width//2
                x2=self.pos.x<=self.g.bat.pos.x+self.g.bat.width//2
                if x1 and x2:
                    if self.surprise>0:
                        self.DoSurprise(self.surprise)
                    else:
                        if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_wood,0),1)
                        n=euclid.Vector2((self.pos.x-self.g.bat.pos.x)/(self.g.bat.width//2),1.0-(self.pos.x-self.g.bat.pos.x)/(self.g.bat.width//2))
                        if abs(n.y)<0.25:
                            if n.y<0:
                                n.y=-0.25
                            else:
                                n.y=0.25
                            n.x=1-n.y
                        self.dir=n.normalize()
                        self.pos.y=self.g.bat.maxy+self.radius
                    return
        # Bottom of bat
        if self.dir.y>0:
            if self.pos.y+self.radius>=self.g.bat.miny and self.pos.y-self.radius<self.g.bat.miny:
                x1=self.pos.x>=self.g.bat.pos.x-self.g.bat.width//2
                x2=self.pos.x<=self.g.bat.pos.x+self.g.bat.width//2
                if x1 and x2:
                    if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_wood,0),1)
                    n=euclid.Vector2(0.0,-1.0)
                    self.dir=self.dir.reflect(n)
                    self.pos.y=self.g.bat.miny-self.radius
                    return
        # Left of bat
        if self.dir.x>0:
            if self.pos.x+self.radius>=self.g.bat.pos.x-self.g.bat.width//2 and self.pos.x-self.radius<self.g.bat.pos.x-self.g.bat.width//2:
                y1=self.pos.y<=self.g.bat.maxy
                y2=self.pos.y>=self.g.bat.miny
                if y1 and y2:
                    if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_wood,0),1)
                    n=euclid.Vector2(-1.0,0.0)
                    self.dir=self.dir.reflect(n)
                    self.pos.x=self.g.bat.pos.x-self.g.bat.width//2-self.radius
                    return
        # Right of bat
        if self.dir.x<0:
            if self.pos.x-self.radius<=self.g.bat.pos.x+self.g.bat.width//2 and self.pos.x+self.radius>self.g.bat.pos.x+self.g.bat.width//2:
                y1=self.pos.y<=self.g.bat.maxy
                y2=self.pos.y>=self.g.bat.miny
                if y1 and y2:
                    if self.g.sound: BASS_ChannelPlay(BASS_SampleGetChannel(self.g.wav_wood,0),1)
                    n=euclid.Vector2(1.0,0.0)
                    self.dir=self.dir.reflect(n)
                    self.pos.x=self.g.bat.pos.x+self.g.bat.width//2+self.radius
                    return

##    def Walls(self,dt):
##        for w in self.g.walls:
##            if self.i.intersect(l):
##                p=self.p+self.v*dt+0.5*self.a*dt*dt
##                c=euclid.Circle(p,self.r)
##                d=c.intersect(l)
##                if d:
##                    self.Reflect(self.Normal(l))
##            else:
##                continue

    def Loop(self,dt):
        if self.g.state & self.g.PRE:
            self.pos.x=self.g.bat.pos.x
            self.pos.y=self.g.bat.pos.y+32
        else:
            d=dt*self.g.ball_speed
            self.pos+=self.dir*d
            self.ChkWallCollisions()
            self.ChkBatCollisions()
    
    def Draw(self):
        if self.alive:
            self.img.set_position(self.pos.x,self.pos.y)
            self.img.draw()
